package server;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import abstractions.ServerServices;


public class rmiServer extends UnicastRemoteObject {
    
	protected rmiServer() throws RemoteException { }

	private static final long serialVersionUID = 1L;
	public static final File SERIALIZED_STUB_FILE = new File("compute-stubs.bin");
	public static final String POLICY_FILE_NAME = "allow_all.policy";
	   
	//engine is the class the object that implements Service Services
	public ServerServices rmiServerHandler(Class<?> clazzToAddToServerCodebase, ServerServices engine, int port){	
        System.setProperty("java.rmi.server.codebase", clazzToAddToServerCodebase
                .getProtectionDomain().getCodeSource().getLocation().toString());

        System.setProperty("java.security.policy", getLocationOfPolicyFile());

        if(System.getSecurityManager() == null)
        	System.setSecurityManager(new SecurityManager());
		
		try {
			UnicastRemoteObject.unexportObject(engine, true);
			ServerServices engineStub = (ServerServices)UnicastRemoteObject.exportObject(engine, port);
			ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(SERIALIZED_STUB_FILE));
			try {
				out.writeObject(engineStub);
			} finally {
				out.close();
			}	
			return engineStub;
		}
		catch(Exception e) {
			e.printStackTrace();
		}    	
		return null;
	}

    public static String getLocationOfPolicyFile() {
        try {
            File tempFile = File.createTempFile("rmi-base", ".policy");
            InputStream is = rmiServer.class.getResourceAsStream(POLICY_FILE_NAME);
            BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));
            int read = 0;
            while((read = is.read()) != -1) {
                writer.write(read);
            }
            writer.close();
            tempFile.deleteOnExit();
            return tempFile.getAbsolutePath();
        }
        catch(IOException e) {
            throw new RuntimeException(e);
        }
    }
}